Data and subsetting

Raw data

Raw data files for the ophthalmoscope, edge sharpness and focal length contain one row for each eye sampled. For most individuals, there are four rows of data: Right eye 1 & eye 2 and left eye 1 & eye 2.

Raw data file for behaviour contains data from both the optimal and challenging light arenas.

Not using lens3_hanging_drops.csv as this was the first set of data that were collected. The images are overexposed and positioning isnt’ quite right. This makes focal length estimation unreliable.

# Load raw data

# Ophthalmoscope
oph_data <- read.csv("lens3_ophthalmoscope.csv", header = TRUE)

# Hanging drops
edge_data <- read.csv("edge_sharpness_long.csv", header = TRUE)

focal_data <- read.csv("back_focal_length.csv", header = TRUE)

# Behaviour
behaviour_data <- read.csv("lens3_behaviour.csv", header = TRUE)

# na.strings converts "NA", "" and " " into na within the body of the file

Figures

Ophthalmoscope

#LE1
LE1_oph <- oph_data %>%
  filter(eye == "LE1") %>%
  ggplot(aes(y= bestimagereciprocal, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  labs(title=NULL,x="Left Eye 1", y = "Object distance (mm)") +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  scale_y_continuous(breaks = c(-0.2, -0.1, 0, 0.1, 0.2)) +
  geom_jitter(shape = 19, size = 2, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 30, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 30, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

LE1_oph

#LE2
LE2_oph <- oph_data %>%
  filter(eye == "LE2") %>%
  ggplot(aes(y= bestimagereciprocal, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  labs(title=NULL,x="Left Eye 2", y = "Object distance (mm)") +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  scale_y_continuous(breaks = c(-0.2, -0.1, 0, 0.1, 0.2)) +
  geom_jitter(shape = 19, size = 2, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 30, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 30, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

LE2_oph

#RE1
RE1_oph <- oph_data %>%
  filter(eye == "RE1") %>%
  ggplot(aes(y= bestimagereciprocal, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  labs(title=NULL,x="Right Eye 1", y = "Object distance (mm)") +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  scale_y_continuous(breaks = c(-0.2, -0.1, 0, 0.1, 0.2)) +
  geom_jitter(shape = 19, size = 2, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 30, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 30, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

RE1_oph

#RE2

RE2_oph <- oph_data %>%
  filter(eye == "RE2") %>%
  ggplot(aes(y= bestimagereciprocal, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = 17, outlier.size = 2, position = "dodge2") + # Changing outlier shape
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  labs(title=NULL,x="Right Eye 2", y = "Object distance (mm)") +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  scale_y_continuous(breaks = c(-0.2, -0.1, 0, 0.1, 0.2)) +
  geom_jitter(shape = 19, size = 2.5, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 30, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 30, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

RE2_oph

# Making the individual boxes narrow and putting them next to each other like the osmosis paper figures

# Creating new column with the eye and probe identity to make this easier. Might be a better way to do this?
oph_data <- oph_data %>%
  mutate(eye_probe = paste(eye, probe, sep="_"))

# Reordering factors so control and probe boxes are grouped together
oph_data$eye_probe <- factor(oph_data$eye_probe,
                          c("LE1_control", "RE1_control", "LE2_control", "RE2_control", "LE1_lens3_191", "RE1_lens3_191", "LE2_lens3_191", "RE2_lens3_191", "LE1_lens3_249", "RE1_lens3_249", "LE2_lens3_249", "RE2_lens3_249"))

# Plot for all E1s

E1_LR_oph <- oph_data %>%
  filter(grepl('E1', eye)) %>% #grepl stands for grep logical. It is a funciton that searches for matches or a string or a string vector
  ggplot(aes(y= bestimagereciprocal, x = eye_probe, fill = eye_probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#009E73", "#E69F00",  "#E69F00", "#D55E00", "#D55E00")) +
  labs(title=NULL,x="Eye 1", y = "Object distance (mm)") +
  scale_x_discrete(labels = c('Left', 'Right', 'Left', 'Right', 'Left', 'Right')) +
  scale_y_continuous(breaks = c(-0.2, -0.1, 0, 0.1, 0.2)) +
  geom_jitter(shape = 19, size = 2, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 30, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 30, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

E1_LR_oph 

# Trying custom facet grid labels and using the labeller function
probe.labs <- c("control" = "Control","lens3_191" = "Probe 1", "lens3_249" = "Probe 2")

# Trying to make multilevel x-axes

E1_LR_oph <- E1_LR_oph + facet_grid(~ probe, scales = "free", labeller = labeller(probe = probe.labs)) 

# Changing text size of facet grid labels
E1_LR_oph <- E1_LR_oph + theme(strip.text.x = element_text(size = 20, face = "bold"))

# Customising facet appearance
E1_LR_oph <- E1_LR_oph + theme(strip.background = element_rect(size = 1.5, linetype = "solid"))

E1_LR_oph

# Plot for all E2s

E2_LR_oph <- oph_data %>%
  filter(grepl('E2', eye)) %>% #grepl stands for grep logical. It is a funciton that searches for matches or a string or a string vector
  ggplot(aes(y= bestimagereciprocal, x = eye_probe, fill = eye_probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#009E73", "#E69F00", "#E69F00", "#D55E00", "#D55E00")) +
  labs(title=NULL,x="Eye 2", y = "Object distance (mm)") +
  scale_x_discrete(labels = c('Left', 'Right', 'Left', 'Right', 'Left', 'Right')) +
  scale_y_continuous(breaks = c(-0.2, -0.1, 0, 0.1, 0.2)) +
  geom_jitter(shape = 19, size = 2, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 30, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 30, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

E2_LR_oph 

# Trying custom facet grid labels and using the labeller function
probe.labs <- c("control" = "Control","lens3_191" = "Probe 1", "lens3_249" = "Probe 2")

# Trying to make multilevel x-axes

E2_LR_oph <- E2_LR_oph + facet_grid(~ probe, scales = "free", labeller = labeller(probe = probe.labs)) 

# Changing text size of facet grid labels
E2_LR_oph <- E2_LR_oph + theme(strip.text.x = element_text(size = 20, face = "bold"))

# Customising facet appearance
E2_LR_oph <- E2_LR_oph + theme(strip.background = element_rect(size = 1.5, linetype = "solid"))

E2_LR_oph

#make panels 
fig.a <- E1_LR_oph +
theme(legend.position = "none")

fig.a

fig.b <- E2_LR_oph +
theme(legend.position = "none") +
  labs(y = NULL) + #removes y axis label
  guides(y = "none") #removes y axis line and numbers

fig.b

#use cowplot package to nicely plot the graphs together with a shared common legend.
wide_plot <- plot_grid(fig.a, NULL, fig.b, 
                   #list of plots to arrange in grid
                   rel_widths = c(6, 0.2, 6),
                   align = "h",
                   nrow = 1)

plot_grid(wide_plot)

#print graph
pdf(file = "Figures/ophthalmoscope_wide.pdf", width = 12,  height = 6)
wide_plot
dev.off()
## quartz_off_screen 
##                 2
# stacking the plots on top of each other instead of putting them side to side
fig.a <- E1_LR_oph +
theme(legend.position = "none",
      axis.title.y = element_blank())

fig.a

fig.b <- E2_LR_oph +
theme(legend.position = "none",
      strip.text.x = element_blank())+ #removing facet_grid second x axis label
  labs(y = NULL)

fig.b

#combining plots

long_plot <- plot_grid(fig.a, fig.b,
                       nrow = 2)
plot_grid(long_plot)

#creating common y axis label
y.grob <- textGrob("Object distance (mm)", 
                   gp = gpar(fontface = "bold",
                             fontsize = 30), rot = 90)

#print graph
pdf(file = "Figures/ophthalmoscope_long.pdf", width = 12,  height = 9)
grid.arrange(arrangeGrob(long_plot, left = y.grob)) #adding common y axis label to plot
dev.off()
## quartz_off_screen 
##                 2

Relative Edge Sharpness

# Creating new column with the eye and probe identity
edge_data <- edge_data %>%
  mutate(eye_probe = paste(eye, probe, sep="_"))

# individual eye line plots

#LE1
LE1_edge_plot <- edge_data %>%
  filter(eye == "LE1") %>%
  ggplot(aes(y= contrast, x = distance, group = eye_probe)) +
  #geom_point() +
  stat_smooth(span = 0.1, se = TRUE, aes(fill = eye_probe, colour = eye_probe)) +
  scale_colour_manual(values = c("#009E73", "#E69F00", "#D55E00"), labels = c("Control", "Probe 1", "Probe 2")) +
  scale_fill_manual(values = c("#009E73", "#E69F00", "#D55E00"), labels = c("Control", "Probe 1", "Probe 2")) + # For some reason, if labels are not specified in both colour and fill, they are plotted twice. Weird
  scale_x_continuous("Distance from Back Surface of Lens", 
                     breaks = c(250, 350, 450, 550), 
                     limits = c(185, 600)) +
  scale_y_continuous("Relative Edge Sharpness",
                     breaks = c(1, 1.5, 2.5, 3.5)) +
  theme_classic() +
  theme(axis.title.x = element_text(size = 25, face = "bold", vjust = -1.2),
        axis.title.y = element_text(size = 25, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
        legend.title = element_blank(),
        legend.text = element_text(size = 15))

LE1_edge_plot 

#LE2
LE2_edge_plot <- edge_data %>%
  filter(eye == "LE2") %>%
  ggplot(aes(y= contrast, x = distance, group = eye_probe)) +
  #geom_point() +
  stat_smooth(span = 0.1, se = TRUE, aes(fill = eye_probe, colour = eye_probe))+
  scale_colour_manual(values = c("#009E73", "#E69F00", "#D55E00"), labels = c("Control", "Probe 1", "Probe 2")) +
  scale_fill_manual(values = c("#009E73", "#E69F00", "#D55E00"), labels = c("Control", "Probe 1", "Probe 2")) + # For some reason, if labels are not specified in both colour and fill, they are plotted twice. Weird
  scale_x_continuous("Distance from Back Surface of Lens", 
                     breaks = c(250, 350, 450, 550), 
                     limits = c(185, 600)) +
  scale_y_continuous("Relative Edge Sharpness",
                     breaks = c(1, 2, 3, 4)) +
  theme_classic() +
  theme(axis.title.x = element_text(size = 25, face = "bold", vjust = -1.2),
        axis.title.y = element_text(size = 25, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
        legend.title = element_blank(),
        legend.text = element_text(size = 15))

LE2_edge_plot 

#RE1
RE1_edge_plot <- edge_data %>%
  filter(eye == "RE1") %>%
  ggplot(aes(y= contrast, x = distance, group = eye_probe)) +
  #geom_point() +
   stat_smooth(span = 0.1, se = TRUE, aes(fill = eye_probe, colour = eye_probe)) + 
  scale_colour_manual(values = c("#009E73", "#E69F00", "#D55E00")) +
  scale_fill_manual(values = c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_continuous("Distance from Back Surface of Lens", 
                     breaks = c(250, 350, 450, 550), 
                     limits = c(185, 600)) +
  scale_y_continuous("Relative Edge Sharpness",
                     breaks = c(1, 2, 3, 4)) +
  theme_classic() +
  theme(axis.title.x = element_text(size = 25, face = "bold", vjust = -1.2),
        axis.title.y = element_text(size = 25, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
        legend.position = "none")

RE1_edge_plot 

#RE2
RE2_edge_plot <- edge_data %>%
  filter(eye == "RE2") %>%
  ggplot(aes(y= contrast, x = distance, group = eye_probe, colour = eye_probe)) +
  #geom_point() +
  stat_smooth(span = 0.005, se = TRUE, aes(fill = eye_probe, colour = eye_probe)) + 
  scale_colour_manual(values = c("#009E73", "#E69F00", "#D55E00")) +
  scale_fill_manual(values = c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_continuous("Distance from Back Surface of Lens", 
                     breaks = c(250, 350, 450, 550), 
                     limits = c(185, 600)) +
  scale_y_continuous("Relative Edge Sharpness",
                     breaks = c(1, 2, 3, 4)) +
  theme_classic() +
  theme(axis.title.x = element_text(size = 25, face = "bold", vjust = -1.2),
        axis.title.y = element_text(size = 25, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
        legend.position = "none")

RE2_edge_plot 

# Unused but useful bit of code
# Melting the data by distance to make it long format edge_data <- melt(edge_data, id.vars = "distance", value.name = "contrast")

# Pulling information from rows and trying to organise it into a new column: edge_data_long$left <- str_detect(edge_data_long$variable, "L") 
pdf(file = "Figures/LE2_edge_sharpness.pdf", width = 8,  height = 6)
LE2_edge_plot
dev.off()
## quartz_off_screen 
##                 2

Back focal length

Only using the 2nd (taller) peak for this because the 1st is often hard to detect, especially in knockdowns. Went through the image series side-by-side to verify these.

#LE1
LE1_focal <- focal_data %>%
  filter(eye == "LE1") %>%
  ggplot(aes(y= peak_2_um, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x="Left Eye 1", y = "Back focal length") +
  geom_jitter(shape = 19, size = 2, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 25, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 25, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

LE1_focal

#LE2
LE2_focal <- focal_data %>%
  filter(eye == "LE2") %>%
  ggplot(aes(y= peak_2_um, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x="Left Eye 2", y = "Back focal length") +
  geom_jitter(shape = 19, size = 3, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 30, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 30, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

LE2_focal

RE1_focal <- focal_data %>%
  filter(eye == "RE1") %>%
  ggplot(aes(y= peak_2_um, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x="Right Eye 1", y = "Back focal length") +
  geom_jitter(shape = 19, size = 2, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 30, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 30, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

RE1_focal

#RE2
RE2_focal <- focal_data %>%
  filter(eye == "RE2") %>%
  ggplot(aes(y= peak_2_um, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x="Right Eye 2", y = "Back focal length") +
  geom_jitter(shape = 19, size = 2, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 30, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 30, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

RE2_focal

# scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
# scale_y_continuous(breaks = c(-0.2, -0.1, 0, 0.1, 0.2)) +
pdf(file = "Figures/LE2_back_focal.pdf", width = 8.5,  height = 8.5)
LE2_focal
dev.off()
## quartz_off_screen 
##                 2

Behaviour

# Creating total strike and percentage hunting success columns
behaviour_data <- behaviour_data %>%
  mutate(total_strikes = missed_strikes + succesful_strikes) %>%
  mutate(missed_dead_prey_strikes_NA_removed = missed_dead_prey_strikes) %>% # duplicating the missed dead prey strikes column because NAs need to be turned to 0s to properly calculate % hunting success. 
  replace_na(list(missed_dead_prey_strikes_NA_removed = 0)) %>%
  mutate(hunting_success = (succesful_strikes - (dead_prey_strikes - missed_dead_prey_strikes_NA_removed))/3 * 100)

Normal light conditions

## Horizontal arena

# missed strikes
missed_strikes_horizontal <- behaviour_data %>%
  filter(arena == "horizontal" & light_environment == "normal") %>%
  ggplot(aes(y= missed_strikes, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "Missed Strikes") +
  geom_jitter(shape = 19, size = 3.5, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 25, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 25, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

missed_strikes_horizontal

# successful strikes
succesful_strikes_horizontal <- behaviour_data %>%
  filter(arena == "horizontal" & light_environment == "normal") %>%
  ggplot(aes(y= succesful_strikes, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "Succesful Strikes") +
  geom_jitter(shape = 19, size = 3.5, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 25, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 25, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

succesful_strikes_horizontal

# latency
latency_horizontal <- behaviour_data %>%
  drop_na(latency_min) %>%
  filter(arena == "horizontal" & light_environment == "normal") %>%
  ggplot(aes(y= latency_min, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "Latency (min)") +
  geom_jitter(shape = 19, size = 3.5, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 40, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 40, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 30, face = "bold"),
                                 legend.position = "none")

latency_horizontal

# hunting success
hunting_horizontal <- behaviour_data %>%
  filter(arena == "horizontal" & light_environment == "normal") %>%
  ggplot(aes(y = hunting_success, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA, position = position_dodge(0.8)) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "% Hunting success") +
  geom_dotplot(aes(fill = NULL, alpha = 0.1), binaxis = 'y', stackdir = 'center', # using geom_dotplot here instead of geom_jitter so that the points are stacked horizontally and centre aligned (stackdir). Important as there are only 3 values for hunting success and geom_jitter makes it seem like there are more.
        stackratio = 1.5, dotsize = 0.7, position = position_dodge(0.8)) + #stackratio adjusts distance between points 
  theme_classic() +
  theme(axis.title.x = element_text(size = 40, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 40, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 30, face = "bold"),
        legend.position = "none")

hunting_horizontal

# total strikes
total_strikes_horizontal <- behaviour_data %>%
  filter(arena == "horizontal" & light_environment == "normal") %>%
  ggplot(aes(y= total_strikes, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "Total Strikes") +
  geom_jitter(shape = 19, size = 3.5, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 25, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 25, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

total_strikes_horizontal

## Vertical arena

# missed strikes
missed_strikes_vertical <- behaviour_data %>%
  filter(arena == "vertical" & light_environment == "normal") %>%
  ggplot(aes(y= missed_strikes, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "Missed Strikes") +
  geom_jitter(shape = 19, size = 3.5, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 25, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 25, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

missed_strikes_vertical

# successful strikes
succesful_strikes_vertical <- behaviour_data %>%
  filter(arena == "vertical" & light_environment == "normal") %>%
  ggplot(aes(y= succesful_strikes, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "Succesful Strikes") +
  geom_jitter(shape = 19, size = 3.5, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 25, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 25, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

succesful_strikes_vertical

# latency
latency_vertical <- behaviour_data %>%
  drop_na(latency_min) %>%
  filter(arena == "vertical" & light_environment == "normal") %>%
  ggplot(aes(y= latency_min, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "Latency (min)") +
  geom_jitter(shape = 19, size = 3.5, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 30, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 30, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 25, face = "bold"),
                                 legend.position = "none")

latency_vertical

# hunting success
hunting_vertical <- behaviour_data %>%
  filter(arena == "vertical" & light_environment == "normal") %>%
  ggplot(aes(y = hunting_success, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA, position = position_dodge(0.8)) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "% Hunting success") +
  geom_dotplot(aes(fill = NULL, alpha = 0.1), binaxis = 'y', stackdir = 'center',
        stackratio = 1.5, dotsize = 0.7, position = position_dodge(0.8)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 40, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 40, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 30, face = "bold"),
        legend.position = "none")

hunting_vertical

# total strikes
total_strikes_vertical <- behaviour_data %>%
  filter(arena == "vertical" & light_environment == "normal") %>%
  ggplot(aes(y= total_strikes, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "Total Strikes") +
  geom_jitter(shape = 19, size = 3.5, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 25, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 25, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

total_strikes_vertical

Dark conditions

96% LEDs covered and UV supplementation removed

## Horizontal arena

# missed strikes
dark_missed_strikes_horizontal <- behaviour_data %>%
  filter(arena == "horizontal" & light_environment == "dark") %>%
  ggplot(aes(y= missed_strikes, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "Missed Strikes") +
  geom_jitter(shape = 19, size = 3.5, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 25, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 25, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

dark_missed_strikes_horizontal

# successful strikes
dark_succesful_strikes_horizontal <- behaviour_data %>%
  filter(arena == "horizontal" & light_environment == "dark") %>%
  ggplot(aes(y= succesful_strikes, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "Succesful Strikes") +
  geom_jitter(shape = 19, size = 3.5, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 25, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 25, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

dark_succesful_strikes_horizontal

# latency
dark_latency_horizontal <- behaviour_data %>%
  drop_na(latency_min) %>%
  filter(arena == "horizontal" & light_environment == "dark") %>%
  ggplot(aes(y= latency_min, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "Latency (min)") +
  geom_jitter(shape = 19, size = 3.5, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 40, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 40, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 30, face = "bold"),
                                 legend.position = "none")

dark_latency_horizontal

# hunting success
dark_hunting_horizontal <- behaviour_data %>%
  filter(arena == "horizontal" & light_environment == "dark") %>%
  ggplot(aes(y = hunting_success, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA, position = position_dodge(0.8)) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "% Hunting success") +
  geom_dotplot(aes(fill = NULL, alpha = 0.1), binaxis = 'y', stackdir = 'center',
        stackratio = 1.5, dotsize = 0.7, position = position_dodge(0.8)) +
  theme_classic() +
  theme(axis.title.x = element_text(size = 40, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 40, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 30, face = "bold"),
        legend.position = "none")

dark_hunting_horizontal

# total strikes
dark_total_strikes_horizontal <- behaviour_data %>%
  filter(arena == "horizontal" & light_environment == "dark") %>%
  ggplot(aes(y= total_strikes, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "Total Strikes") +
  geom_jitter(shape = 19, size = 3.5, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 25, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 25, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

dark_total_strikes_horizontal

## Vertical arena

# missed strikes
dark_missed_strikes_vertical <- behaviour_data %>%
  filter(arena == "vertical" & light_environment == "dark") %>%
  ggplot(aes(y= missed_strikes, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "Missed Strikes") +
  geom_jitter(shape = 19, size = 3.5, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 25, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 25, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

dark_missed_strikes_vertical

# successful strikes
dark_succesful_strikes_vertical <- behaviour_data %>%
  filter(arena == "vertical" & light_environment == "dark") %>%
  ggplot(aes(y= succesful_strikes, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "Succesful Strikes") +
  geom_jitter(shape = 19, size = 3.5, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 25, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 25, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

dark_succesful_strikes_vertical

# latency
dark_latency_vertical <- behaviour_data %>%
  drop_na(latency_min) %>%
  filter(arena == "vertical" & light_environment == "dark") %>%
  ggplot(aes(y= latency_min, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "Latency (min)") +
  geom_jitter(shape = 19, size = 3.5, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 30, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 30, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 25, face = "bold"),
                                 legend.position = "none")

dark_latency_vertical

# hunting success
dark_hunting_vertical <- behaviour_data %>%
  filter(arena == "vertical" & light_environment == "dark") %>%
  ggplot(aes(y = hunting_success, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA, position = position_dodge(0.8)) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "% Hunting success") +
  geom_dotplot(aes(fill = NULL, alpha = 0.1), binaxis = 'y', stackdir = 'center',
        stackratio = 1.5, dotsize = 0.7, position = position_dodge(0.8)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 40, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 40, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 30, face = "bold"),
        legend.position = "none")

dark_hunting_vertical

# total strikes
dark_total_strikes_vertical <- behaviour_data %>%
  filter(arena == "vertical" & light_environment == "dark") %>%
  ggplot(aes(y= total_strikes, x = probe, fill = probe)) +
  geom_boxplot(alpha = 0.8, outlier.shape = NA) +
  scale_fill_manual(values=c("#009E73", "#E69F00", "#D55E00")) +
  scale_x_discrete(labels = c('Control', 'Probe 1', 'Probe 2')) +
  labs(title=NULL,x= "", y = "Total Strikes") +
  geom_jitter(shape = 19, size = 3.5, alpha = 0.7, position = position_jitter(0.1)) + 
  theme_classic() +
  theme(axis.title.x = element_text(size = 25, face = "bold", vjust = -0.15),
        axis.title.y = element_text(size = 25, face = "bold", vjust = 1.8),
        axis.text = element_text(size = 20, face = "bold"),
                                 legend.position = "none")

dark_total_strikes_vertical

Statistics

Ophthalmoscope

## Test for normality

# Building the linear model
oph_model <- lm(bestimagereciprocal ~ probe, data = oph_data)

# Creating a QQ plot of residuals
ggqqplot(residuals(oph_model))

# Test for normality
shapiro_test(residuals(oph_model))
## # A tibble: 1 × 3
##   variable             statistic    p.value
##   <chr>                    <dbl>      <dbl>
## 1 residuals(oph_model)     0.925 0.00000340
# p < 0.05 so can't assume normality

# Checking normality assumption by groups
oph_data %>%
  group_by(probe) %>%
  shapiro_test(bestimagereciprocal)
## # A tibble: 3 × 4
##   probe     variable            statistic         p
##   <chr>     <chr>                   <dbl>     <dbl>
## 1 control   bestimagereciprocal     0.853 0.0000516
## 2 lens3_191 bestimagereciprocal     0.915 0.00540  
## 3 lens3_249 bestimagereciprocal     0.962 0.195
# again p < 0.05 so can't assume normality

# Creating QQ plots for each group level
ggqqplot(oph_data, "bestimagereciprocal", facet.by = "probe")

# Probe 2 (lens3_249) is the only one that looks normal. Other two are kinda wonky

# Using a Kruskal-Wallis test
res_oph_kw <- compare_means(bestimagereciprocal ~ probe, data = oph_data, 
              group.by = "eye", method = 'kruskal.test')
res_oph_kw
## # A tibble: 4 × 7
##   eye   .y.                     p p.adj p.format p.signif method        
##   <chr> <chr>               <dbl> <dbl> <chr>    <chr>    <chr>         
## 1 LE1   bestimagereciprocal 0.218  0.87 0.22     ns       Kruskal-Wallis
## 2 LE2   bestimagereciprocal 0.569  1    0.57     ns       Kruskal-Wallis
## 3 RE1   bestimagereciprocal 0.236  0.87 0.24     ns       Kruskal-Wallis
## 4 RE2   bestimagereciprocal 0.939  1    0.94     ns       Kruskal-Wallis
# No significant changes in focused state with lens3 knockdown - all eyes

Edge sharpness series

# Building linear models for each curve 

# LE2
edge_model_control_LE2 <- lm(contrast ~ distance,
                             data = edge_data,
                             subset = eye_probe == "LE2_control")

edge_model_249_LE2 <- lm(contrast ~ distance,
                             data = edge_data,
                             subset = eye_probe == "LE2_lens3_249")

edge_model_191_LE2 <- lm(contrast ~ distance,
                             data = edge_data,
                             subset = eye_probe == "LE2_lens3_191")

# kruskal.test(edge_model_249_LE2, edge_model_control_LE2, edge_model_191_LE2)

Back focal length

## Test for normality

# Building the linear model
focal_model <- lm(peak_2_um ~ probe, data = focal_data)

# Creating a QQ plot of residuals
ggqqplot(residuals(focal_model))

# Test for normality
shapiro_test(residuals(focal_model))
## # A tibble: 1 × 3
##   variable               statistic p.value
##   <chr>                      <dbl>   <dbl>
## 1 residuals(focal_model)     0.986   0.316
# p > 0.05 so assuming normality

# Checking normality assumption by groups
focal_data %>%
  group_by(probe) %>%
  shapiro_test(peak_2_um)
## # A tibble: 3 × 4
##   probe     variable  statistic     p
##   <chr>     <chr>         <dbl> <dbl>
## 1 control   peak_2_um     0.973 0.633
## 2 lens3_191 peak_2_um     0.988 0.945
## 3 lens3_249 peak_2_um     0.965 0.261
# again p > 0.05 so assuming normality

# Creating QQ plots for each group level
ggqqplot(focal_data, "peak_2_um", facet.by = "probe")

# Control and Probe 1 look normal. Probe 2 is kinda wonky. But will proceed with Gaussian stats

# Using an ANOVA test
res_focal_aov <- compare_means(peak_2_um ~ probe, data = focal_data, 
              group.by = "eye", method = 'anova')
res_focal_aov
## # A tibble: 4 × 7
##   eye   .y.            p p.adj p.format p.signif method
##   <chr> <chr>      <dbl> <dbl> <chr>    <chr>    <chr> 
## 1 RE1   peak_2_um 0.0878  0.35 0.088    ns       Anova 
## 2 RE2   peak_2_um 0.885   1    0.885    ns       Anova 
## 3 LE1   peak_2_um 0.833   1    0.833    ns       Anova 
## 4 LE2   peak_2_um 0.828   1    0.828    ns       Anova
# No significant changes in back focal length with lens3 knockdown - all eyes